<template>
  <div class="tool-container">
    <div class="tool-header">
      <h1 class="tool-title">Base64 编解码工具</h1>
      <p class="tool-description">
        支持文本和文件的 Base64 编码与解码，可以快速进行数据转换
      </p>
    </div>

    <div class="tool-content">
      <el-tabs v-model="activeTab" class="demo-tabs">
        <el-tab-pane label="文本编解码" name="text">
          <div class="text-mode">
            <el-form>
              <el-form-item label="输入文本">
                <el-input
                  v-model="inputText"
                  type="textarea"
                  :rows="6"
                  placeholder="请输入要编码或解码的文本"
                  resize="vertical"
                />
              </el-form-item>

              <el-form-item>
                <div class="action-buttons">
                  <el-button type="primary" @click="encodeText">
                    <el-icon><Upload /></el-icon>编码
                  </el-button>
                  <el-button type="success" @click="decodeText">
                    <el-icon><Download /></el-icon>解码
                  </el-button>
                  <el-button @click="clearText">
                    <el-icon><Delete /></el-icon>清空
                  </el-button>
                </div>
              </el-form-item>

              <el-form-item label="结果输出">
                <el-input
                  v-model="outputText"
                  type="textarea"
                  :rows="6"
                  placeholder="编码/解码结果将显示在这里"
                  readonly
                  resize="vertical"
                />
              </el-form-item>

              <el-form-item>
                <el-button 
                  type="primary" 
                  plain 
                  @click="copyOutput"
                  :disabled="!outputText"
                >
                  <el-icon><CopyDocument /></el-icon>复制结果
                </el-button>
              </el-form-item>
            </el-form>
          </div>
        </el-tab-pane>

        <el-tab-pane label="文件编解码" name="file">
          <div class="file-mode">
            <el-upload
              class="file-uploader"
              drag
              action=""
              :auto-upload="false"
              :show-file-list="false"
              @change="handleFileChange"
            >
              <el-icon class="el-icon--upload"><Upload /></el-icon>
              <div class="el-upload__text">
                将文件拖到此处，或<em>点击上传</em>
              </div>
              <template #tip>
                <div class="el-upload__tip">
                  支持任意类型文件，建议大小不超过10MB
                </div>
              </template>
            </el-upload>

            <div v-if="selectedFile" class="file-info">
              <el-descriptions :column="1" border>
                <el-descriptions-item label="文件名">
                  {{ selectedFile.name }}
                </el-descriptions-item>
                <el-descriptions-item label="文件大小">
                  {{ formatFileSize(selectedFile.size) }}
                </el-descriptions-item>
                <el-descriptions-item label="文件类型">
                  {{ selectedFile.type || '未知' }}
                </el-descriptions-item>
              </el-descriptions>

              <div class="file-actions">
                <el-button type="primary" @click="encodeFile">
                  <el-icon><Upload /></el-icon>编码文件
                </el-button>
                <el-button type="success" @click="decodeFile">
                  <el-icon><Download /></el-icon>解码并下载
                </el-button>
                <el-button @click="clearFile">
                  <el-icon><Delete /></el-icon>清除
                </el-button>
              </div>
            </div>
          </div>
        </el-tab-pane>
      </el-tabs>
    </div>

    <div class="tool-footer">
      <el-alert
        v-if="errorMessage"
        :title="errorMessage"
        type="error"
        show-icon
        closable
      />
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { ElMessage } from 'element-plus'
import { Upload, Download, Delete, CopyDocument } from '@element-plus/icons-vue'

const activeTab = ref('text')
const inputText = ref('')
const outputText = ref('')
const selectedFile = ref(null)
const errorMessage = ref('')

// 文本编解码
const encodeText = () => {
  try {
    if (!inputText.value) {
      ElMessage.warning('请输入要编码的文本')
      return
    }
    outputText.value = btoa(inputText.value)
    errorMessage.value = ''
  } catch (error) {
    errorMessage.value = '编码失败：' + error.message
  }
}

const decodeText = () => {
  try {
    if (!inputText.value) {
      ElMessage.warning('请输入要解码的Base64文本')
      return
    }
    outputText.value = atob(inputText.value)
    errorMessage.value = ''
  } catch (error) {
    errorMessage.value = '解码失败：输入的不是有效的Base64编码'
  }
}

const clearText = () => {
  inputText.value = ''
  outputText.value = ''
  errorMessage.value = ''
}

const copyOutput = async () => {
  try {
    await navigator.clipboard.writeText(outputText.value)
    ElMessage.success('复制成功')
  } catch (error) {
    ElMessage.error('复制失败：' + error.message)
  }
}

// 文件编解码
const handleFileChange = (file) => {
  selectedFile.value = file.raw
  errorMessage.value = ''
}

const encodeFile = () => {
  if (!selectedFile.value) {
    ElMessage.warning('请先选择文件')
    return
  }

  const reader = new FileReader()
  reader.onload = () => {
    try {
      const base64 = reader.result.split(',')[1]
      outputText.value = base64
      activeTab.value = 'text'
      ElMessage.success('文件编码完成')
    } catch (error) {
      errorMessage.value = '文件编码失败：' + error.message
    }
  }
  reader.onerror = () => {
    errorMessage.value = '文件读取失败'
  }
  reader.readAsDataURL(selectedFile.value)
}

const decodeFile = () => {
  if (!selectedFile.value) {
    ElMessage.warning('请先选择文件')
    return
  }

  try {
    const reader = new FileReader()
    reader.onload = () => {
      try {
        const content = reader.result
        const byteCharacters = atob(content)
        const byteNumbers = new Array(byteCharacters.length)
        for (let i = 0; i < byteCharacters.length; i++) {
          byteNumbers[i] = byteCharacters.charCodeAt(i)
        }
        const byteArray = new Uint8Array(byteNumbers)
        const blob = new Blob([byteArray])
        
        const link = document.createElement('a')
        link.href = URL.createObjectURL(blob)
        link.download = 'decoded_' + selectedFile.value.name
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
        
        ElMessage.success('文件解码并下载成功')
      } catch (error) {
        errorMessage.value = '文件解码失败：不是有效的Base64编码'
      }
    }
    reader.onerror = () => {
      errorMessage.value = '文件读取失败'
    }
    reader.readAsText(selectedFile.value)
  } catch (error) {
    errorMessage.value = '文件处理失败：' + error.message
  }
}

const clearFile = () => {
  selectedFile.value = null
  errorMessage.value = ''
}

const formatFileSize = (bytes) => {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}
</script>

<style scoped>
.text-mode,
.file-mode {
  margin-top: 20px;
}

.action-buttons {
  display: flex;
  gap: 12px;
  margin-bottom: 20px;
}

.file-uploader {
  margin-bottom: 20px;
}

.file-info {
  margin-top: 20px;
}

.file-actions {
  margin-top: 20px;
  display: flex;
  gap: 12px;
}

:deep(.el-upload-dragger) {
  width: 100%;
  height: 200px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

:deep(.el-icon--upload) {
  font-size: 48px;
  color: var(--el-color-primary);
  margin-bottom: 16px;
}

.el-upload__text {
  font-size: var(--el-font-size-base);
  color: var(--el-text-color-regular);
  margin-bottom: 8px;
}

.el-upload__text em {
  color: var(--el-color-primary);
  font-style: normal;
}

.el-upload__tip {
  font-size: var(--el-font-size-small);
  color: var(--el-text-color-secondary);
}

@media (max-width: 768px) {
  .action-buttons,
  .file-actions {
    flex-direction: column;
    gap: 8px;
  }

  :deep(.el-upload-dragger) {
    height: 160px;
  }
}
</style> 